package cn.itcast.jx.shiro;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.apache.log4j.Logger;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import cn.itcast.jx.domain.Module;
import cn.itcast.jx.domain.Role;
import cn.itcast.jx.domain.User;
import cn.itcast.jx.service.UserService;


public class AuthRealm extends AuthorizingRealm{
	private static Logger log = Logger.getLogger(AuthRealm.class);
	UserService userService;
	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	//授权
	protected AuthorizationInfo doGetAuthorizationInfo(
			PrincipalCollection principals) {
		log.info("执行授权...");
		//获取登录用户的权限，配合jsp页面中的shiro标签进行控制
		
		//1.根据realm的名称,找到PrincipalCollection中存入的用户的名称
		User user = (User) principals.fromRealm(this.getName()).iterator().next();
		//2.根据对象导航,得到当前用户的角色列表
		Set<Role> roles = user.getRoles();
		//3.将所有的模块装在一起
		List<String> list = new ArrayList<>();
		for (Role role :roles) {
			Set<Module> modules = role.getModules();
			for (Module module : modules) {
				list.add(module.getCpermission());
			}
		}		
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		info.addStringPermissions(list);
		return info;
	}

	//认证
	/*
	 * shiro规则，按用户名查找，如果没找到返回null，如果查找到返回密码，shiro自动和调用subject.login()中的密码值进行比较
	 * 密码一致，登录成功；密码不一致，密码错误。
	 */
	protected AuthenticationInfo doGetAuthenticationInfo(
			AuthenticationToken token) throws AuthenticationException {
			log.info("执行认证...");
			UsernamePasswordToken  upToken= (UsernamePasswordToken)token;
			//从logout退出时
			if(upToken.getPassword() == null) {
				return null;
			}
			User user = userService.findUserByName(upToken.getUsername());
			//该用户不存在
			if(user == null) {
				return null;
			}	
			//用户存在
			SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassword(),this.getName());
			//返回密码，自动比较密码
			return info;
		}
	}

